package com.zbkj.client.task;

import com.zbkj.client.dao.MaterialMapper;
import com.zbkj.client.service.MaterialService;
import com.zbkj.client.utils.FileUtil;
import com.zbkj.common.model.assets.Material;
import com.zbkj.common.model.client.digital.DgVideo;
import com.zbkj.client.vo.DpVideoCjVo;
import com.zbkj.common.model.client.workbench.IntoPieces;
import com.zbkj.common.model.client.workbench.VideoTemplateFinal;
import com.zbkj.common.utils.OssUtil;
import com.zbkj.service.service.DgVideoService;
import com.zbkj.service.service.IntoPiecesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

@Slf4j
@Component
public class DpVideoUrlUpdateTask {
    @Resource
    private DgVideoService dgVideoService;
    @Resource
    private ThreadPoolTaskScheduler taskScheduler;

    @Autowired
    private IntoPiecesService intoPiecesService;

    @Autowired
    private MaterialService materialService;

    @Autowired
    private MaterialMapper materialMapper;

    public void start(DgVideo dgVideo, DpVideoCjVo vo) {
        schedule(dgVideo, vo, 0);
    }

    private void schedule(DgVideo dgVideo, DpVideoCjVo vo, int retryCount) {
        long delay = retryCount == 0 ? 0 : 2000; // 首次立即，后续2秒重试
        taskScheduler.schedule(() -> {
            try {
                doTask(dgVideo, vo, retryCount);
            } catch (Exception e) {
                log.error("DpVideoUrlUpdateTask-定时任务异常", e);
            }
        }, new Date(System.currentTimeMillis() + delay));
    }

    private void doTask(DgVideo dgVideo, DpVideoCjVo vo, int retryCount) {
        if (dgVideo == null || vo == null) return;
        // 重新查库获取最新对象
        DgVideo lastDgVideo = dgVideoService.getById(dgVideo.getId());
        if (lastDgVideo == null || lastDgVideo.getIsDel() == 1) {
            log.warn("DpVideoUrlUpdateTask-未找到合成视频的记录，id={}", dgVideo.getId());
            return;
        }
        Integer userId = lastDgVideo.getUserId();
        Integer merId = lastDgVideo.getMerId();
        String videoUrl = vo.getVideo_url();
        String subtitleUrl = vo.getSubtitle_data_url();
        String previewUrl = vo.getPreview_url();
        boolean success = true;
        try {
            if (videoUrl != null && !videoUrl.isEmpty() && (lastDgVideo.getOssVideoUrl() == null || lastDgVideo.getOssVideoUrl().isEmpty())) {
                String fileTypeLoop = FileUtil.getExtensionWithURI(videoUrl);

                String fileName = "video_" + System.currentTimeMillis() + "." + fileTypeLoop;
                String ossVideoUrl = OssUtil.uploadFromUrlToOss(videoUrl, fileName, userId, merId, "video", "dpvideo", "noasset");
                if (ossVideoUrl != null) {
                    lastDgVideo.setOssVideoUrl(ossVideoUrl);

                    //成功了就保存到素材或者成片
                    Map<String, Object> saveLocation = lastDgVideo.getSaveLocation();
                    if (saveLocation != null) {

                        String sourceUrl = lastDgVideo.getOssVideoUrl();
                        String fileNameCopy = System.currentTimeMillis() + "." + fileTypeLoop;

                        String newUrl = OssUtil.copyOssFile(sourceUrl, "client", merId,userId, "piece" , fileNameCopy);

                        if ("piece".equals(saveLocation.get("module"))){
                            Integer saveId = insertPiece(lastDgVideo, newUrl);
                            //更新videoTemplate的值
                            saveLocation.put("id", saveId);
                            lastDgVideo.setSaveLocation(saveLocation);
                            dgVideoService.updateById(lastDgVideo);
                        } else if ("material".equals(saveLocation.get("module"))){
                            Integer saveId = insertMaterial(lastDgVideo, newUrl);
                            //更新videoTemplate的值
                            saveLocation.put("id", saveId);
                            lastDgVideo.setSaveLocation(saveLocation);
                            dgVideoService.updateById(lastDgVideo);
                        }
                    }
                } else {
                    success = false;
                }
            }
            if (subtitleUrl != null && !subtitleUrl.isEmpty() && (lastDgVideo.getOssSubtitleDataUrl() == null || lastDgVideo.getOssSubtitleDataUrl().isEmpty())) {
                String fileTypeLoop1 = FileUtil.getExtensionWithURI(subtitleUrl);

                String fileName = "subtitle_" + System.currentTimeMillis() + "." + fileTypeLoop1;
                String ossSubtitleUrl = OssUtil.uploadFromUrlToOss(subtitleUrl, fileName, userId, merId, "subtitle", "dpvideo", "client");
                if (ossSubtitleUrl != null) {
                    lastDgVideo.setOssSubtitleDataUrl(ossSubtitleUrl);
                } else {
                    success = false;
                }
            }
            if (previewUrl != null && !previewUrl.isEmpty() && (lastDgVideo.getOssPreviewUrl() == null || lastDgVideo.getOssPreviewUrl().isEmpty())) {
                String fileTypeLoop2 = FileUtil.getExtensionWithURI(previewUrl);

                String fileName = "preview_" + System.currentTimeMillis() + "." + fileTypeLoop2;
                String ossPreviewUrl = OssUtil.uploadFromUrlToOss(previewUrl, fileName, userId, merId, "image", "dpvideo", "client");
                if (ossPreviewUrl != null) {
                    lastDgVideo.setOssPreviewUrl(ossPreviewUrl);
                } else {
                    success = false;
                }
            }
            lastDgVideo.setUpdateTime(new Date());
            dgVideoService.updateById(lastDgVideo);
        } catch (Exception e) {
            log.error("DpVideoUrlUpdateTask-异步上传OSS或更新数据库异常", e);
            success = false;
        }
        if (!success && retryCount < 3) {
            log.warn("DpVideoUrlUpdateTask-上传OSS或更新数据库失败，准备重试，第{}次", retryCount + 1);
            schedule(lastDgVideo, vo, retryCount + 1);
        } else if (!success) {
            log.error("DpVideoUrlUpdateTask-重试3次后仍失败");
        }
    }

    private Integer insertPiece(DgVideo dgVideo, String newUrl) {
        IntoPieces intoPieces = new IntoPieces();
        intoPieces.setName(dgVideo.getName());
        intoPieces.setIsFolder(0);
        intoPieces.setUserId(dgVideo.getUserId());
        intoPieces.setMerId(dgVideo.getMerId());

        intoPieces.setUrl(newUrl);
        intoPieces.setModule("template");
        intoPieces.setSource("template");
        intoPieces.setFileRealType("video/mp4");
        Integer saveParentId = (Integer) dgVideo.getSaveLocation().get("parent_id");
        if (saveParentId != null && saveParentId == 0) {
            intoPieces.setCompleteFolder("/");
            intoPieces.setParentId(0);
        }else{
            IntoPieces byId = intoPiecesService.getById(saveParentId);
            intoPieces.setCompleteFolder(byId.getCompleteFolder() + saveParentId + "/");
            intoPieces.setParentId(saveParentId);
        }

        intoPiecesService.save(intoPieces);

        return intoPieces.getId();

    }

    private Integer insertMaterial(DgVideo dgVideo, String newUrl) {
        Material material = new Material();
        material.setName(dgVideo.getName());
        material.setIsFolder(0);
        material.setUserId(dgVideo.getUserId());
        material.setMerId(dgVideo.getMerId());
        material.setUrl(newUrl);
        material.setModule("template");
        material.setSource("template");
        material.setFileRealType("video/mp4");
        Integer saveParentId = (Integer) dgVideo.getSaveLocation().get("parent_id");

        if (saveParentId != null && saveParentId == 0) {
            material.setCompleteFolder("/");
            material.setParentId(0);
        }else{
            Material byId = materialService.getById(saveParentId);
            material.setCompleteFolder(byId.getCompleteFolder() + saveParentId + "/");
            material.setParentId(saveParentId);
        }

        materialMapper.insert(material);
        return material.getId();
    }
} 